<!DOCTYPE html>
<html lang="en">
  <head>
    <meta charset="UTF-8" />
    <meta http-equiv="X-UA-Compatible" content="IE=edge" />
    <meta name="viewport" content="width=device-width, initial-scale=1.0" />
    <title>12.闭包在实战中的应用</title>
  </head>
  <body>
    <button index="1">按钮1</button>
    <button index="2">按钮2</button>
    <button index="3">按钮3</button>
    <button index="4">按钮4</button>
    <button index="5">按钮5</button>

    <script>
      let btns = document.querySelectorAll("button");

      // for(var i = 0 ; i < btns.length ; i++) {
      //    (function(n) {
      //     // 伪数组全局变量的onclick引用了一个函数，而在函数内部又访问了 n 所以自执行函数创建的闭包不会消失
      //     btns[i].onclick = function() {
      //         console.log(`我是第${n}个按钮`)
      //     }
      //    })(i)
      // }

      //   for (var i = 0; i < btns.length; i++) {
      //     btns[i].onclick = (function (n) {
      //       // 返回一个函数赋值给全局的dom节点的onclick事件属性引用着，所以当前自执行函数的执行栈也不会消失，
      //       // 所以在执行返回的这个函数的时候就能在就近的作用域中找见闭包内的 n 了
      //       return function () {
      //         console.log(`我是第${n}个按钮`);
      //       };
      //     })(i);
      //   }

      //   for (let i = 0; i < btns.length; i++) {
      //     btns[i].onclick = function () {
      //       console.log(`我是第${i}个按钮`);
      //     };
      //   }

    //   for (let i = 0; i < btns.length; i++) {
    //     btns[i].myIndex = i
    //     btns[i].onclick = function () {
    //       console.log(`我是第${btns[i].myIndex}个按钮`);
    //     };
    //   }

    // document.body.onclick = function(e) {
    //     let {target} = e
    //     if(target.tagName === "BUTTON") {
    //         let index = target.getAttribute('index')
    //         console.log(Number(index))
    //     }
    // }


    // console.log(a, b, c)
    // var a = 12,
    //     b = 13,
    //     c = 14;
    // function fn(a) {
    //     console.log(a, b, c)
    //     a = 100
    //     c = 200
    //     console.log(a, b, c)
    // }
    // b = fn(10)
    // console.log(a, b, c);

    // undefined undefined undefined

    // 10 13 14

    // 100 13 200

    // 12 undefined 200

    // 全局作用域
    // 先变量提升
    // var i
    // function A() {}
    // var y
    // function B() {}

    // 代码执行
    // 创建一个EC(A)   
    // 创建VO(A scope<VO(A), VO(G)>
    // A() 函数执行返回一个函数让全局的y引用（所以这个执行栈不能销毁）

    // 函数执行，它的上级上下文是谁。和函数在哪执行没有关系，上级上下文是他的[[scope]],
    // 所以在哪定义的函数，它的上级上下文就是谁。

    var i = 0
    function A() {
        var i = 10
        function x() {
            console.log(i)
        }
        return x
    }
    var y = A()
    y()   // 打印 i 在VO(A) 中找到了 i = 10

    // 创建 EC(B)
    // 创建 VO(B)
    // 创建 scope<VO(B),VO(G)>
    // 创建私有变量 i = 20
    // 创建执行栈 EC(Y)
    // VO(Y)
    // 作用域链 scope<VO(Y), VO(B), VO(G)>  
    function B() {
        var i = 20
        y()  // 10
    }
    B()
    </script>
  </body>
</html>
